home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / mysql / scripts / fill_help_tables next >
Text File  |  2005-04-01  |  16KB  |  604 lines

  1. #!/usr/bin/perl
  2. #
  3. # Copyright (C) 2003 MySQL AB
  4. # For a more info consult the file COPYRIGHT distributed with this file.
  5. #
  6. # This script generates the SQL statements required by mysql_install_db to
  7. # fill up the tables for the server-side online function help, which can be
  8. # invoked with "help <function>" from the MySQL client.
  9. #
  10. # Usage:
  11. #   fill_help_tables OPTIONS  < manual.texi > fill_help_tables.sql
  12. #  
  13. #  --help           display this helpscreen and exit
  14. #  --verbose        print information about help completeness to STDERR
  15. #  --lexems=path    path to file with lexems. it is used with verbose option.
  16. #                       default value is ../sql/lex.h
  17. # Examples:
  18. #  ./fill_help_tables --help
  19. #  ./fill_help_tables --verbose < manual.texi > fill_help_tables.sql
  20. #  ./fill_help_tables < manual.texi > fill_help_tables.sql
  21. # Please note, that you first need to update Docs/manual.texi with the
  22. # manual file from the separate "mysqldoc" BitKeeper-Tree! The manual.texi
  23. # included in the source tree is just an empty stub file - the full manual
  24. # is now maintained in a separate tree.
  25. #
  26. # extra tags in manual.texi:
  27. #
  28. #    @c help_category <category_name>[@<parent_category_name>]
  29. #
  30. #    @c description_for_help_topic <topic_name>  <keyword1> <keyword2>
  31. #        ....
  32. #    @c end_description_for_help_topic
  33. #
  34. #    @c example_for_help_topic <topic_name>
  35. #    @example
  36. #        ....
  37. #    @end example
  38. #
  39. #
  40. # Original version by Victor Vagin <vva@mysql.com>
  41. #
  42.  
  43. use strict;
  44. use Getopt::Long;
  45.  
  46. my $insert_portion_size= 15;
  47. my $error_prefix= "---- help parsing errors :";
  48.  
  49. my $path_to_lex_file= "../sql/lex.h";
  50. my $verbose_option= 0;
  51. my $help_option= 0;
  52.  
  53. my $cur_line= 0;
  54. my $count_errors= 0;
  55.  
  56. GetOptions(
  57.   "help",\$help_option,
  58.   "verbose",\$verbose_option,
  59.   "lexems=s",\$path_to_lex_file
  60. );
  61.  
  62. if ($help_option ne 0)
  63. {
  64.   print <<_HELP;
  65.  
  66. This script generates the SQL statements required by mysql_install_db to
  67. fill up the tables for the server-side online function help, which can be
  68. invoked with "help <function>" from the MySQL client.
  69.  
  70. Usage:
  71.   fill_help_tables OPTIONS  < manual.texi > fill_help_tables.sql
  72.   
  73.   --help           display this helpscreen and exit
  74.   --verbose        print information about help completeness to STDERR
  75.   --lexems=path    path to file with lexems. it is used with verbose option.
  76.                        default value is ../sql/lex.h
  77.  
  78. Examples:
  79.   ./fill_help_tables --help
  80.   ./fill_help_tables --verbose < manual.texi > fill_help_tables.sql
  81.   ./fill_help_tables < manual.texi > fill_help_tables.sql
  82.     
  83. _HELP
  84.   exit;
  85. }
  86.  
  87. my $current_category= "";
  88. my $current_parent_category= "";
  89. my $next_example_for_topic= "";
  90.  
  91. my %topics; 
  92. my %categories;
  93. my %keywords;
  94.  
  95. $categories{Contents}->{__parent_category__}= "";
  96.  
  97. sub print_error
  98. {
  99.   my ($text)= @_;
  100.   if ($count_errors==0)
  101.   {
  102.     print STDERR "$error_prefix\n";
  103.   }
  104.   print STDERR "line $cur_line : $text";
  105.   $count_errors++;
  106. }
  107.  
  108. sub add_topic_to_category
  109. {
  110.   my ($topic_name)= @_;
  111.  
  112.   $categories{$current_category}->{$topic_name}= $topics{$topic_name};
  113.   my $category= $categories{$current_category};
  114.   $category->{__name__}= $current_category;
  115.     
  116.   if (exists($category->{__parent_category__}))
  117.   {
  118.     my $old_parent= $category->{__parent_category__};
  119.     if ($old_parent ne $current_parent_category)
  120.     {
  121.       print_error "wrong parent for $current_category\n";
  122.     }
  123.   }
  124.  
  125.   if ($current_parent_category ne "")
  126.   {
  127.     $category->{__parent_category__}= $current_parent_category;
  128.   }
  129.     
  130.   if (exists($topics{$topic_name}->{category}))
  131.   {
  132.     my $old_category= $topics{$topic_name}->{category};
  133.     if ($old_category ne $category)
  134.     {
  135.       print_error "wrong category for $topic_name (first one's \"$old_category->{__name__}\" second one's \"$current_category\")\n";
  136.     }
  137.   }
  138.     
  139.   $topics{$topic_name}->{category}= $category;    
  140. }
  141.  
  142. sub add_example
  143. {
  144.   my ($topic_name,$example)= @_;
  145.     
  146.   $topic_name=~ tr/a-z/A-Z/;
  147.  
  148.   if (exists($topics{$topic_name}->{example}))
  149.   {
  150.     print_error "double example for $topic_name\n";
  151.   }
  152.     
  153.   $topics{$topic_name}->{example}= $example;    
  154.   add_topic_to_category($topic_name);
  155. }
  156.  
  157. sub add_description
  158. {
  159.   my ($topic_name,$description)= @_;
  160.     
  161.   $topic_name=~ tr/a-z/A-Z/;
  162.     
  163.   if (exists($topics{$topic_name}->{description}))
  164.   {
  165.     print_error "double description for $topic_name\n";
  166.   }
  167.   $topics{$topic_name}->{description}= $description;
  168.   add_topic_to_category($topic_name);
  169. }
  170.  
  171. sub add_keyword
  172. {
  173.   my ($topic_name,$keyword)= @_;
  174.     
  175.   $topic_name=~ tr/a-z/A-Z/;
  176.   $keyword=~ tr/a-z/A-Z/; 
  177.     
  178.   push(@{$topics{$topic_name}->{keywords}},$keyword);
  179.   if (exists($keywords{$keyword}->{$topic_name}))
  180.   {
  181.     print_error "double keyword $keyword for $topic_name\n";
  182.   }
  183.   $keywords{$keyword}->{$topic_name}= $topics{$topic_name};
  184. }
  185.  
  186. sub prepare_name
  187. {
  188.   my ($a)= @_;
  189.     
  190.   $a =~ s/(\@itemize \@bullet)/  /g;
  191.   $a =~ s/(\@end itemize)/  /g;
  192.   $a =~ s/(\@end multitable)/  /g;
  193.   $a =~ s/(\@end table)/  /g;
  194.   $a =~ s/(\@cindex(.*?)\n)/  /g;
  195.   $a =~ s/(\@multitable \@columnfractions(.*?)\n)/  /g;
  196.   $a =~ s/(\@node(.*?)\n)/  /g;
  197.   $a =~ s/(\@tab)/\t/g;
  198.   $a =~ s/\@item/  /g;
  199.   $a =~ s/\@minus\{\}/-/g;
  200.   $a =~ s/\@dots\{\}/.../g;
  201.   $a =~ s/\@var\{((.|\n)+?)\}/$1/go;
  202.   $a =~ s/\@command\{((.|\n)+?)\}/$1/go;
  203.   $a =~ s/\@code\{((.|\n)+?)\}/$1/go;
  204.   $a =~ s/\@strong\{(.+?)\}/$1/go;
  205.   $a =~ s/\@samp\{(.+?)\}/'$1'/go;
  206.   $a =~ s/\@emph\{((.|\n)+?)\}/\/$1\//go;
  207.   $a =~ s/\@xref\{((.|\n)+?)\}/See also : [$1]/go;
  208.   $a =~ s/\@ref\{((.|\n)+?)\}/[$1]/go;
  209.   $a =~ s/\'/\'\'/g;
  210.   $a =~ s/\\/\\\\/g;
  211.   $a =~ s/\`/\`\`/g;
  212.  
  213.   $a =~ s/\@table \@code/  /g;
  214.   $a =~ s/\(\)//g;
  215.   $a =~ s/\"/\\\"/g;
  216.  
  217.   $a =~ s/((\w|\s)+)\(([\+-=><\/%*!<>\s]+)\)/$3/gxs;
  218.   $a =~ s/([\+-=><\/%*!<>\s]+)\(((\w|\s)+)\)/$1/gxs;
  219.   $a =~ s/((\w|\s)+)\((.+)\)/$1/gxs;
  220.   
  221.   $a =~ s/((\s)+)$//g;
  222.                                                     
  223.   return $a;
  224. }
  225.  
  226. sub prepare_description
  227. {
  228.   my ($a)= @_;
  229.  
  230.   $a =~ s/(\@itemize \@bullet\n)//g;
  231.   $a =~ s/(\@c help_keyword (.*?)\n)//g;
  232.   $a =~ s/(\@end itemize\n)//g;
  233.   $a =~ s/(\@end example\n)//g;
  234.   $a =~ s/(\@example\n)//g;
  235.   $a =~ s/(\@{)/{/g;
  236.   $a =~ s/(\@})/}/g;
  237.   $a =~ s/(\@end multitable)/  /g;
  238.   $a =~ s/(\@end table)/  /g;
  239.   $a =~ s/(\@cindex(.*?)\n)//g;
  240.   $a =~ s/(\@findex(.*?)\n)//g;
  241.   $a =~ s/(\@table(.*?)\n)//g;
  242.   $a =~ s/(\@multitable \@columnfractions(.*?)\n)/  /g;
  243.   $a =~ s/(\@node(.*?)\n)/  /g;
  244.   $a =~ s/(\@tab)/\t/g;
  245.   $a =~ s/\@itemx/  /g;
  246.   $a =~ s/(\@item\n(\s*?))(\S)/ --- $3/g;
  247.   $a =~ s/(\@item)/  /g;
  248.   $a =~ s/(\@tindex\s(.*?)\n)//g;
  249.   $a =~ s/(\@c\s(.*?)\n)//g;
  250.   $a =~ s/\@minus\{\}/-/g;
  251.   $a =~ s/\@dots\{\}/.../g;
  252.   $a =~ s/\@var\{((.|\n)+?)\}/$1/go;
  253.   $a =~ s/\@command\{((.|\n)+?)\}/$1/go;
  254.   $a =~ s/\@code\{((.|\n)+?)\}/$1/go;
  255.   $a =~ s/\@strong\{(.+?)\}/$1/go;
  256.   $a =~ s/\@samp\{(.+?)\}/'$1'/go;
  257.   $a =~ s/\@emph\{((.|\n)+?)\}/\/$1\//go;
  258.   $a =~ s/\@xref\{((.|\n)+?)\}/See also : [$1]/go;
  259.   $a =~ s/\@ref\{((.|\n)+?)\}/[$1]/go;
  260.   $a =~ s/\@w\{((.|\n)+?)\}/$1/go;
  261.   $a =~ s/\@strong\{((.|\n)+?)\}/\n!!!!\n$1\n!!!!\n/go;
  262.   $a =~ s/\@file\{((.|\n)+?)\}/\*$1/go;
  263.   $a =~ s/\\/\\\\/g;
  264.   $a =~ s/\n\n$/\n/g;
  265.   $a =~ s/\n\n$/\n/g;
  266.   $a =~ s/\n\n$/\n/g;
  267.   $a =~ s/\n\n$/\n/g;
  268.   $a =~ s/\n\n$/\n/g;
  269.   $a =~ s/\n/\\n/g;
  270.   $a =~ s/\"/\\\"/g;
  271.  
  272.   $a =~ s/\@table \@code/  /g;
  273.  
  274.   return $a;
  275. }
  276.  
  277. sub prepare_example
  278. {
  279.   my ($a)= @_;
  280.  
  281.   $a =~ s/(^\@c for_help_topic(.*?)\n)//g;
  282.  
  283.   $a =~ s/\@var\{((.|\n)+?)\}/$1/go;
  284.   $a =~ s/\@dots\{\}/.../g;
  285.   $a =~ s/\\/\\\\/g;
  286.   $a =~ s/(\@{)/{/g;
  287.   $a =~ s/(\@})/}/g;
  288.   $a =~ s/(\@\@)/\@/g;
  289.   $a =~ s/(\n*?)$//g;
  290.   $a =~ s/\n/\\n/g;
  291.   $a =~ s/\"/\\\"/g;
  292.     
  293.   return $a;
  294. }
  295.  
  296. sub parse_example
  297. {
  298.   return if (!($_=~/\@example/));
  299.   return if ($next_example_for_topic eq "");
  300.     
  301.   my $topic_name= $next_example_for_topic;
  302.   $next_example_for_topic= "";
  303.   my $text= "";
  304.     
  305.   while (<>)
  306.   {
  307.     $cur_line++;
  308.     last if ($_=~/\@end example/);
  309.     $text .= $_;
  310.   }
  311.     
  312.   $text= prepare_example($text);
  313.   $topic_name= prepare_name($topic_name);
  314.   add_example($topic_name,$text) if ($topic_name ne "");
  315. }
  316.  
  317. sub parse_example_for_topic
  318. {
  319.   my ($for_topic)= m|\@c example_for_help_topic (.+?)$|;
  320.   return if ($for_topic eq "");
  321.     
  322.   $next_example_for_topic= $for_topic;    
  323. }
  324.  
  325. sub parse_description
  326. {
  327.   my ($topic_description)= m|\@c description_for_help_topic (.+?)$|;
  328.   return if ($topic_description eq "");
  329.     
  330.   my ($topic_name,$topic_keywords)= split(/  /,$topic_description);
  331.     
  332.   if ($topic_name eq "" || $topic_keywords eq "")
  333.   {
  334.     $topic_name= $topic_description;
  335.   }
  336.   else
  337.   {
  338.     my $keyword;
  339.     foreach $keyword (split(/ /,$topic_keywords))
  340.     {
  341.       add_keyword($topic_name,$keyword) if ($keyword ne "");
  342.     }
  343.   }
  344.     
  345.   my $text= "";
  346.     
  347.   while (<>)
  348.   {
  349.     $cur_line++;
  350.     last if ($_=~/\@c end_description_for_help_topic/);
  351.     $text .= $_;
  352.   }
  353.     
  354.   $text= prepare_description($text);
  355.   $topic_name= prepare_name($topic_name);
  356.   add_description($topic_name,$text);
  357. }
  358.  
  359. sub parse_category
  360. {
  361.   my ($c_name,$pc_name)= m|\@c help_category (.+?)\@(.+?)$|;
  362.  
  363.   if ($pc_name ne "")
  364.   {
  365.     $current_category= prepare_name($c_name);
  366.     $current_parent_category= prepare_name($pc_name);
  367.   }
  368.   else
  369.   {
  370.     my ($c_name)=m|\@c help_category (.+?)$|;
  371.     return if ($c_name eq "");
  372.  
  373.     $current_category= prepare_name($c_name);
  374.     $current_parent_category= "Contents"
  375.   }
  376. }
  377.  
  378. # parse manual:
  379.  
  380. while (<>)
  381. {
  382.   parse_example_for_topic ();
  383.   parse_example           ();
  384.   parse_description       ();    
  385.   parse_category          ();
  386.   $cur_line++;
  387. }
  388.  
  389. # test results of parsing:
  390.  
  391. sub print_bad_names
  392. {
  393.   my($names,$prompt)= @_;
  394.   if (scalar(@{$names}))
  395.   {
  396.     print STDERR "\n-------------- $prompt : \n\n";
  397.     my $name;
  398.     foreach $name (@{$names})
  399.     {
  400.       print STDERR "$name\n";
  401.     }
  402.     print STDERR "\n";
  403.   }
  404. }
  405.  
  406. sub print_verbose_errors
  407. {
  408.   my($name_of_log_file)= @_;
  409.  
  410.   my @without_help;
  411.   my @description_with_at;
  412.   my @example_with_at;
  413.   my @without_description;
  414.   my @without_example;
  415.     
  416.   print STDERR "\n-------------- parameters of help completeness : \n\n";
  417.     
  418.   my $count_lex= 0;
  419.   if (!open (TLEX,"<$path_to_lex_file"))
  420.   {
  421.     print STDERR "Error opening lex file \"$path_to_lex_file\" $!\n";
  422.   }
  423.   else
  424.   {    
  425.     for (<TLEX>)
  426.     {
  427.       my ($a,$lex,$b)=m|(.+?)\"(.+?)\"(.+?)$|;
  428.       next if ($lex eq "");
  429.       $count_lex++;
  430.       next if (exists($topics{$lex}) || exists($keywords{$lex}));
  431.       push(@without_help,$lex);
  432.     }
  433.     close(TLEX);
  434.     print STDERR "number of lexems in \"$path_to_lex_file\" - $count_lex\n";
  435.   }
  436.     
  437.   my $name;
  438.   my @topic_names= keys(%topics);
  439.   foreach $name (@topic_names)
  440.   {
  441.     my $topic= $topics{$name};
  442.     push(@description_with_at,$name) if ($topic->{description}=~/\@/);
  443.     push(@example_with_at,$name) if ($topic->{example}=~/\@/);
  444.     push(@without_description,$name) if (!exists($topic->{description}));
  445.     push(@without_example,$name) if (!exists($topic->{example}));
  446.   }
  447.     
  448.   my $count_categories= scalar(keys(%categories));
  449.   print STDERR "number of help categories          - ",$count_categories,"\n";
  450.   my $count_topics= scalar(@topic_names);
  451.   print STDERR "number of help topics              - ",$count_topics,"\n";
  452.   my $count_keywords= scalar(keys(%keywords));
  453.   print STDERR "number of help keywords            - ",$count_keywords,"\n";
  454.     
  455.   my $count_without_help= scalar(@without_help);
  456.   my $percent_without_help= $count_lex ?
  457.                             int (($count_without_help/$count_lex)*100) :
  458.                             "100";
  459.   print_bad_names(\@without_help,"lexems without help (".
  460.                             $count_without_help." ~ ".
  461.                             $percent_without_help."%)");
  462.   print_bad_names(\@description_with_at,
  463.           " topics below have symbol \'@\' in their descriptions.\n".
  464.           "it's probably the litter from 'texi' tags (script needs fixing)");
  465.   print_bad_names(\@example_with_at,
  466.           " topics below have symbol \'@\' in their examples.\n".
  467.           "it's probably the litter from 'texi' tags (script needs fixing)");
  468.   print_bad_names(\@without_description,"topics without description");
  469.     
  470.   my $count_without_example= scalar(@without_example);
  471.   my $percent_without_example= $count_topics ?
  472.                             int (($count_without_example/$count_topics)*100) :
  473.                             "100";
  474.   print_bad_names(\@without_example,"topics without example (".
  475.                             $count_without_example." ~ ".
  476.                             $percent_without_example."%)");
  477. }
  478.  
  479. print_verbose_errors if ($verbose_option ne 0);
  480.  
  481. # output result 
  482.  
  483. sub print_insert_header
  484. {
  485.   my($count,$header)= @_;
  486.     
  487.   if ($count % $insert_portion_size ne 0) {
  488.     print ",";
  489.   } else {
  490.     print ";\n" if ($count ne 0);
  491.     print "$header";
  492.   }
  493. }
  494.  
  495. print <<EOF;
  496. -- Copyright (C) 2000-2005 MySQL AB
  497. -- 
  498. -- This program is free software; you can redistribute it and/or modify
  499. -- it under the terms of the GNU General Public License as published by
  500. -- the Free Software Foundation; either version 2 of the License, or
  501. -- (at your option) any later version.
  502. -- 
  503. -- This program is distributed in the hope that it will be useful,
  504. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  505. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  506. -- GNU General Public License for more details.
  507. -- 
  508. -- You should have received a copy of the GNU General Public License
  509. -- along with this program; if not, write to the Free Software
  510. -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  511.  
  512. EOF
  513. print "delete from help_topic;\n";
  514. print "delete from help_category;\n";
  515. print "delete from help_keyword;\n";
  516. print "delete from help_relation;\n\n";
  517.  
  518. my @category_names= keys(%categories);
  519. if (scalar(@category_names))
  520. {
  521.   my $cat_name;
  522.   my $count= 0;
  523.   foreach $cat_name (@category_names)
  524.   {
  525.     $categories{$cat_name}->{__id__}= $count;
  526.     $count++;
  527.   }
  528.  
  529.   my $header= "insert into help_category ".
  530.             "(help_category_id,name,parent_category_id) values ";
  531.   $count= 0;
  532.   foreach $cat_name (@category_names)
  533.   {
  534.     print_insert_header($count,$header);
  535.     my $parent_cat_name= $categories{$cat_name}->{__parent_category__};
  536.     my $parent_cat_id= $parent_cat_name eq "" 
  537.         ? "-1" : $categories{$parent_cat_name}->{__id__};
  538.     print "($count,\"$cat_name\",$parent_cat_id)";
  539.     $count++;
  540.   }
  541.   printf ";\n\n";
  542. }
  543.  
  544. my @topic_names= keys(%topics);
  545. if (scalar(@topic_names))
  546. {
  547.   my $header= "insert into help_topic ".
  548.       "(help_topic_id,help_category_id,name,description,example) values ";
  549.   my $topic_name;
  550.   my $count= 0;
  551.   foreach $topic_name (@topic_names)
  552.   {
  553.     print_insert_header($count,$header);
  554.     my $topic= $topics{$topic_name};
  555.     print "($count,";
  556.     print "$topic->{category}->{__id__},";
  557.     print "\"$topic_name\",";
  558.     print "\"$topic->{description}\",";
  559.     print "\"$topic->{example}\")";
  560.     $topics{$topic_name}->{__id__}= $count;
  561.     $count++;
  562.   }
  563.   printf ";\n\n";
  564. }
  565.  
  566. my @keywords_names= keys(%keywords);
  567. if (scalar(@keywords_names))
  568. {
  569.   my $header= "insert into help_keyword (help_keyword_id,name) values ";
  570.   my $keyword_name;
  571.   my $count= 0;
  572.   foreach $keyword_name (@keywords_names)
  573.   {
  574.     print_insert_header($count,$header);
  575.     print "($count,\"$keyword_name\")";
  576.     $count++;
  577.   }
  578.   printf ";\n\n";
  579.     
  580.   $header= "insert into help_relation ".
  581.     "(help_topic_id,help_keyword_id) values ";
  582.   $count= 0;
  583.   my $count_keyword= 0;
  584.   foreach $keyword_name (@keywords_names)
  585.   {
  586.     my $topic_name;
  587.     foreach $topic_name (keys(%{$keywords{$keyword_name}}))
  588.     {
  589.       print_insert_header($count,$header);
  590.       print "($topics{$topic_name}->{__id__},$count_keyword)";
  591.       $count++;
  592.     }
  593.     $count_keyword++;
  594.   }
  595.   printf ";\n\n";
  596. }
  597.  
  598. if ($count_errors)
  599. {
  600.   print STDERR "$count_errors errors !!!\n";
  601.   exit 1;
  602. }
  603.